Skip to main content
Glama

Stock Market Research Assistant

by kvssankar
sse-server.js•5.13 kB
// sse-server.js import express from "express"; import cors from "cors"; import { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js"; import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js"; import { AnthropicAdapter } from "@reacter/openapitools"; import { loadConfig } from "./utils.js"; import path from "path"; import { fileURLToPath } from "url"; // Get the directory name of the current module const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); export default async function startSseServer() { // Load configuration const mcpConfig = loadConfig(); // Set default refresh time to 1 day (in minutes) if not specified const refreshTimeMinutes = mcpConfig.refresh_time_minutes || 24 * 60; // 1 day default const app = express(); app.use(cors()); app.use(express.json()); app.use(express.urlencoded({ extended: true })); const toolsAdapter = new AnthropicAdapter( mcpConfig.api_key || path.join(__dirname, "openapitools"), { verbose: false, // Needs to be false to work with claude desktop (stdio), turn it on for sse } ); toolsAdapter.setEnvironmentVariables(mcpConfig.envs); const toolHandler = await toolsAdapter.createAnthropicToolHandler(); // Cache for tools let toolsCache = { tools: [], lastFetchTime: 0, }; // Function to fetch and update tools cache async function refreshToolsCache() { // Check if tool_names array exists and has items const toolNames = mcpConfig.tool_names && mcpConfig.tool_names.length > 0 ? mcpConfig.tool_names : undefined; // Fetch tools const tools = await toolsAdapter.getAnthropicTools(toolNames); // Update cache toolsCache.tools = tools; toolsCache.lastFetchTime = Date.now(); return tools; } // Check if cache needs refreshing function shouldRefreshCache() { const cacheAgeMs = Date.now() - toolsCache.lastFetchTime; const refreshThresholdMs = refreshTimeMinutes * 60 * 1000; return cacheAgeMs > refreshThresholdMs || toolsCache.tools.length === 0; } // Initial tools fetch await refreshToolsCache(); const server = new Server( { name: mcpConfig.server_name || "example-server", version: mcpConfig.server_version || "1.0.0", }, { capabilities: { tools: {}, }, } ); server.setRequestHandler(ListToolsRequestSchema, async () => { // Check if cache needs refreshing if (shouldRefreshCache()) { await refreshToolsCache(); } return { tools: toolsCache.tools, }; }); // Add endpoint for manual refresh server.setRequestHandler( { method: "POST", path: "/refresh-tools", }, async () => { try { await refreshToolsCache(); return { success: true, message: "Tools cache refreshed successfully", timestamp: new Date().toISOString(), }; } catch (error) { return { success: false, message: `Error refreshing tools: ${error.message}`, timestamp: new Date().toISOString(), }; } } ); server.setRequestHandler(CallToolRequestSchema, async (request, extra) => { try { const result = await toolHandler({ id: "223", name: request.params.name, input: request.params.arguments, }); return { content: [ { type: "text", text: result.output, }, ], }; } catch (e) { return { content: [ { type: "text", text: `Error: ${e.message}`, }, ], isError: true, }; } }); const transports = {}; app.get("/sse", async (_, res) => { const transport = new SSEServerTransport("/messages", res); transports[transport.sessionId] = transport; res.on("close", () => { delete transports[transport.sessionId]; }); await server.connect(transport); }); app.post("/messages", async (req, res) => { const sessionId = req.query.sessionId; const transport = transports[sessionId]; if (transport) { await transport.handlePostMessage(req, res); } else { res.status(400).send("No transport found for sessionId"); } }); // Also add REST endpoint for manual refresh outside of MCP app.get("/api/refresh-tools", async (req, res) => { try { await refreshToolsCache(); res.json({ success: true, message: "Tools cache refreshed successfully", timestamp: new Date().toISOString(), }); } catch (error) { res.status(500).json({ success: false, message: `Error refreshing tools: ${error.message}`, timestamp: new Date().toISOString(), }); } }); const port = mcpConfig.port || 3001; return new Promise((resolve) => { app.listen(port, mcpConfig.host || "0.0.0.0", () => { resolve(); }); }); }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/kvssankar/openapitools-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server